package com.sangmo.boot.auth.core.handlers.impl;

import com.sangmo.boot.auth.core.AbstractAuthorizeService;
import com.sangmo.boot.auth.core.AccessTokenService;
import com.sangmo.boot.auth.core.AuthorizeCodeService;
import com.sangmo.boot.auth.core.errors.ErrorMessages;
import com.sangmo.boot.auth.core.handlers.BaseAuthorizeHandler;
import com.sangmo.boot.auth.core.interfaces.GrantTokenRequest;
import com.sangmo.boot.auth.core.model.AccessToken;
import com.sangmo.boot.auth.core.model.Client;
import com.sangmo.boot.framework.common.errors.ServiceException;
import com.sangmo.boot.framework.common.errors.StandardErrors;
import com.sangmo.boot.framework.common.session.UserInterface;
import com.sangmo.boot.framework.common.session.UserSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

public class DefaultAuthorizeHandler extends BaseAuthorizeHandler {
    @Autowired private AbstractAuthorizeService abstractAuthorizeService;
    @Autowired private AccessTokenService accessTokenService;
    @Autowired private AuthorizeCodeService authorizeCodeService;

    @Value("${authorize.token.create.always}")
    private boolean alwaysCreateNew = true;

    @Override
    protected AccessToken createToken(Client client, GrantTokenRequest req) {
        UserInterface user = null;

        if (Client.GrantTypes.PASSWORD.equals(req.getGrantType())) {
            user = abstractAuthorizeService.doAuthentication(req.getUsername(), req.getCredential());
            if (null == user) {
                throw new ServiceException(StandardErrors.AUTHORIZED_WRONG.getStatus(),
                        ErrorMessages.AUTH_USER_NAMENOTEXISTS);
            }
        } else if (Client.GrantTypes.CODE.equals(req.getGrantType())) {
            boolean ret = authorizeCodeService.validate(req.getClientId(), req.getUsername(), req.getCredential(), req.getRandomStr());
            if (ret) {
                user = abstractAuthorizeService.createIfNotExists(req.getUsername());
            }
            if (null == user) {
                throw new ServiceException(StandardErrors.AUTHORIZED_WRONG.getStatus(),
                        ErrorMessages.AUTH_USER_CODE_WRONG);
            }
        } else if (Client.GrantTypes.WX_CODE.equals(req.getGrantType())) {


        }
        return accessTokenService.createOrUpdateToken(client, req, alwaysCreateNew);
    }

    @Override
    protected UserSession.Authorize<?> authorize(Client client, AccessToken accessToken) {
        UserSession.Authorize<?> authorize = abstractAuthorizeService.findAuthorize(accessToken.getUsername(), accessToken.getValue());
        authorize.setClientId(client.getId());
        authorize.setToken(accessToken.getValue());
        return authorize;
    }
}
